package com.atguigu.yygh.user.service.impl;

import com.atguigu.yygh.common.exception.YYGHException;
import com.atguigu.yygh.common.utils.JwtHelper;
import com.atguigu.yygh.enums.AuthStatusEnum;
import com.atguigu.yygh.enums.StatusEnum;
import com.atguigu.yygh.model.user.Patient;
import com.atguigu.yygh.model.user.UserInfo;
import com.atguigu.yygh.user.mapper.PatientMapper;
import com.atguigu.yygh.user.mapper.UserInfoMapper;
import com.atguigu.yygh.user.service.PatientService;
import com.atguigu.yygh.user.service.UserInfoService;
import com.atguigu.yygh.vo.user.LoginVo;
import com.atguigu.yygh.vo.user.UserAuthVo;
import com.atguigu.yygh.vo.user.UserInfoQueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private PatientService patientService;

    @Override
    public Map<String, Object> login(LoginVo loginVo) {

        UserInfo userInfo = null;
                //1.获取手机号和验证码
        String phone = loginVo.getPhone();
        String code = loginVo.getCode();
        //2.对手机号和验证码非空校验
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
            throw new YYGHException(20001,"手机号和验证码不能为空");
        }

        //4.合理性校验
        String redisCcode = stringRedisTemplate.opsForValue().get(phone);
        if(StringUtils.isEmpty(redisCcode) || !redisCcode.equals(code)){
            throw new YYGHException(20001,"验证码有误");
        }

        //对oppenId做判断
        String openid = loginVo.getOpenid();
        if(StringUtils.isEmpty(openid)){
            //3.判断用户是否为首次登录,首次登录进行注册,非首次登录进行查询
            QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>();
            queryWrapper.eq("phone",phone); //根据手机号精确查询
            userInfo = baseMapper.selectOne(queryWrapper);

            if(userInfo == null){ //注册
                userInfo = new UserInfo();
                userInfo.setPhone(phone);
                userInfo.setStatus(1);
                baseMapper.insert(userInfo);
            }
        }else { //微信强制绑定手机号登录
            QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>();
            queryWrapper.eq("openid", openid);
            userInfo = baseMapper.selectOne(queryWrapper);
            //根据手机号查询
            QueryWrapper<UserInfo> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("phone",phone);
            UserInfo userInfo1 = baseMapper.selectOne(queryWrapper1);
            //判断根据手机号是否能查到,查不到就更新用户信息,能查到就表示有2条数据就进行合并操作
            if(userInfo1 == null){
                //持久化到数据库
                userInfo.setPhone(phone);
                baseMapper.updateById(userInfo);
            }else {
                userInfo1.setOpenid(userInfo.getOpenid());
                userInfo1.setNickName(userInfo.getNickName());
                baseMapper.updateById(userInfo1); //持久化到数据库中
                baseMapper.deleteById(userInfo.getId()); //删除UserInfo中的id
                BeanUtils.copyProperties(userInfo1,userInfo); //使用手机号查出来的数据覆盖用用户openId查出来的数据
            }
        }

        //5.判断用户状态
        if(userInfo.getStatus() == 0){
            throw new YYGHException(20001,"该用户状态已被锁定");
        }

        Map<String,Object> resultMap = new HashMap<String,Object>();

        //用户名称取值优先级判断真实名称(nane)>NickName(微信名称)>phone(手机号)
        String name = "";
        name = userInfo.getName();
        if(StringUtils.isEmpty(name)){
            name=userInfo.getNickName();
        }
        if(StringUtils.isEmpty(name)){
            name= userInfo.getPhone();
        }
        resultMap.put("name",name);//存用户名

        //生成token
        String token = JwtHelper.createToken(userInfo.getId(), name);
        resultMap.put("token",token);
        return resultMap;
    }

    @Override
    public UserInfo  getUserInfoByOpenId(String openid) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>();
        queryWrapper.eq("openid", openid);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public void updateAuthVo(Long userId, UserAuthVo userAuthVo) {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setName(userAuthVo.getName());
        userInfo.setCertificatesType(userAuthVo.getCertificatesType());
        userInfo.setCertificatesNo(userAuthVo.getCertificatesNo());
        userInfo.setCertificatesUrl(userAuthVo.getCertificatesUrl());
        userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
        userInfo.setUpdateTime(new Date());
        baseMapper.updateById(userInfo);
    }

    //带查询条件的分页
    @Override
    public Page<UserInfo> getPage(Integer pageNum, Integer pageSize, UserInfoQueryVo userInfoQueryVo) {

        Page<UserInfo> page = new Page<UserInfo>(pageNum, pageSize);
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>();

        //判断前端输入的搜索条件是输入框还是手机号,然后qu精确查询
        if(!StringUtils.isEmpty(userInfoQueryVo.getKeyword())){
            //根据姓名还是手机号去查询
            queryWrapper.and(it->it.like("name",userInfoQueryVo.getKeyword()).or().eq("phone",userInfoQueryVo.getKeyword()));
        }
        //根据状态去精确查询
        if(!StringUtils.isEmpty(userInfoQueryVo.getStatus())){
            queryWrapper.eq("status",userInfoQueryVo.getStatus());
        }
        //根据认证状态去查询
        if(!StringUtils.isEmpty(userInfoQueryVo.getAuthStatus())){
            queryWrapper.eq("auth_status",userInfoQueryVo.getAuthStatus());
        }
        //根据≥开始时间之后注册上来的精确查询
        if(!StringUtils.isEmpty(userInfoQueryVo.getCreateTimeBegin())){
            queryWrapper.ge("create_time",userInfoQueryVo.getCreateTimeBegin());
        }
        //根≤开始时间之后注册上来的精确查询
        if(!StringUtils.isEmpty(userInfoQueryVo.getCreateTimeEnd())){
            queryWrapper.le("create_time",userInfoQueryVo.getCreateTimeEnd());
        }
        Page<UserInfo> userInfoPage = baseMapper.selectPage(page, queryWrapper);
        userInfoPage.getRecords().stream().forEach(item->{
            this.packageUserInfo(item);
        });
        //将以上查询到的数据返
        return userInfoPage;
    }

    //根据id修改用户状态
    @Override
    public void lock(Long userId, Integer status) {
        //查询寻状态为0和1的用户状态
        if(status.intValue() == 0 || status.intValue() == 1) {
            UserInfo userInfo = baseMapper.selectById(userId);
            //在内存修改
            userInfo.setStatus(status);
            //持久化到数据库
            baseMapper.updateById(userInfo);
        }
    }

    @Override
    public Map<String, Object> show(Long userId) {
        HashMap<String, Object> resultMap = new HashMap<String, Object>();
        UserInfo userInfo = baseMapper.selectById(userId);
        this.packageUserInfo(userInfo);
        resultMap.put("userInfo",userInfo);

        QueryWrapper<Patient> queryWrapper = new QueryWrapper<Patient>();
        queryWrapper.eq("user_id", userId);
        List<Patient> patients = patientService.list(queryWrapper);
        for (Patient patient : patients) {
            patientService.packagePatient(patient);
        }
        resultMap.put("patients",patients);
        return resultMap;
    }

    @Override
    public void approval(Long userId, Integer authStatus) {
        //认证审批  2通过  -1不通过
        if(authStatus.intValue()==2 || authStatus.intValue()==-1) {
            UserInfo userInfo = baseMapper.selectById(userId);
            userInfo.setAuthStatus(authStatus);
            baseMapper.updateById(userInfo);
        }
    }

    private void packageUserInfo(UserInfo item) {
        Integer status = item.getStatus();
        Integer authStatus = item.getAuthStatus();
        item.getParam().put("statusString", StatusEnum.getDescByCode(status));
        item.getParam().put("authStatusString",AuthStatusEnum.getStatusNameByStatus(authStatus));
    }

    //获取状态和认证状态

}
